﻿using System;
using System.Threading;
using CommonTypes.Server.Operations;
using Server.Model;

namespace Server.Services.Secondary
{
    public class SecondaryMergingManager : MergingManager
    {
        public static readonly Object _secondaryLock = new Object( );

        public static bool AcknowledgeTicket( long ticketId, long logicalClock, ServerData serverData )
        {
            if( serverData.State == ServerState.ESTABLISHED )
            {
                lock( _secondaryLock )
                {
                    System.Console.WriteLine( "I'm processing a ticket request." );

                    if( logicalClock > serverData.ServerLogicalClock )
                    {
                        MergingManager.Synchronize( serverData.ServersInformation.PrimaryId, serverData );
                    }

                    if( logicalClock == serverData.ServerLogicalClock )
                    {
                        serverData.TicketNumber = ticketId;
                        serverData.Operations.Add( serverData.ServerLogicalClock, new TicketGeneration( serverData.ServerLogicalClock, ticketId ) );
                        serverData.ServerLogicalClock++;
                    }

                    Monitor.Pulse( _secondaryLock );
                }
            }
            return true;
        }

        public static bool RegisterClient( String clientId, String clientLocation, long logicalClock, ServerData serverData )
        {
            if( serverData.State == ServerState.ESTABLISHED )
            {
                lock( _secondaryLock )
                {
                    System.Console.WriteLine( "I'm processing a server register." );

                    if( logicalClock > serverData.ServerLogicalClock )
                    {
                        MergingManager.Synchronize( serverData.ServersInformation.PrimaryId, serverData );
                    }

                    if( logicalClock == serverData.ServerLogicalClock )
                    {
                        if( serverData.UsersList.ContainsKey( clientId ) )
                            serverData.UsersList[ clientId ].Location = clientLocation;
                        else
                            serverData.UsersList.Add( clientId, new User( clientId, clientLocation ) );
                        serverData.Operations.Add( serverData.ServerLogicalClock, new AddOperation( serverData.ServerLogicalClock, clientId, clientLocation ) );
                        serverData.ServerLogicalClock++;
                    }

                    Monitor.Pulse( _secondaryLock );
                }
            }
            return true;
        }

        public static bool UnregisterClient( String clientId, long logicalClock, ServerData serverData )
        {
            if( serverData.State == ServerState.ESTABLISHED )
            {
                lock( _secondaryLock )
                {
                    System.Console.WriteLine( "I'm processing a server unregister." );

                    if( logicalClock > serverData.ServerLogicalClock )
                    {
                        MergingManager.Synchronize( serverData.ServersInformation.PrimaryId, serverData );
                    }

                    if( logicalClock == serverData.ServerLogicalClock )
                    {
                        if( serverData.UsersList.ContainsKey( clientId ) )
                            serverData.UsersList.Remove( clientId );
                        serverData.Operations.Add( serverData.ServerLogicalClock, new RemoveOperation( serverData.ServerLogicalClock, clientId ) );
                        serverData.ServerLogicalClock++;
                    }

                    Monitor.Pulse( _secondaryLock );
                }
            }
            return true;
        }
    }
}